#usda 1.0
(
    "This file describes the USD Shader schemata for code generation."
    subLayers = [
        @usd/schema.usda@
    ]
)

over "GLOBAL" (
    customData = {
        string libraryName      = "usdShade"
        string libraryPath      = "pxr/usd/usdShade"
        dictionary libraryTokens = {
            dictionary materialBind = {
                string doc = """The name of the GeomSubset family used to 
                identify face subsets defined for the purpose of binding 
                materials to facesets.
                """
            }
            dictionary full = {
                string doc= """Possible value for 'connectability' metadata on
                a UsdShadeInput. When connectability of an input is set to
                "full", it implies that it can be connected to any input or
                output.
                """
            }
            dictionary interfaceOnly = {
                string doc= """Possible value for 'connectability' metadata on 
                a UsdShadeInput. It implies that the input can only connect to 
                a NodeGraph Input (which represents an interface override, not 
                a render-time dataflow connection), or another Input whose 
                connectability is also 'interfaceOnly'.
                """
            }
            dictionary outputs = {
                string value = "outputs:"
                string doc = """The prefix on shading attributes
                denoting an output.
                """
            }
            dictionary inputs = {
                string value = "inputs:"
                string doc = """The prefix on shading attributes
                denoting an input.
                """
            }
        }
    }
)
{
}

class NodeGraph "NodeGraph" (
    inherits = </Typed>
    doc = """A node-graph is a container for shading nodes, as well as other 
    node-graphs. It has a public input interface and provides a list of public 
    outputs.

    <b>Node Graph Interfaces</b>
    
    One of the most important functions of a node-graph is to host the "interface"
    with which clients of already-built shading networks will interact.  Please
    see \\ref UsdShadeNodeGraph_Interfaces "Interface Inputs" for a detailed
    explanation of what the interface provides, and how to construct and
    use it, to effectively share/instance shader networks.

    <b>Node Graph Outputs</b>

    These behave like outputs on a shader and are typically connected to an 
    output on a shader inside the node-graph.
    """
    customData = {
        string extraIncludes = '''
#include <utility>
#include "pxr/usd/usd/editTarget.h"
#include "pxr/usd/usd/relationship.h"
#include "pxr/usd/usdShade/input.h"
#include "pxr/usd/usdShade/output.h"
#include "pxr/usd/usdShade/shader.h"'''
    }
) {

}


class Material "Material" (
    inherits = </NodeGraph>
    doc = """A Material provides a container into which multiple "render targets"
    can add data that defines a "shading material" for a renderer.  Typically
    this consists of one or more UsdRelationship properties that target
    other prims of type \\em Shader - though a target/client is free to add
    any data that is suitable.  We <b>strongly advise</b> that all targets
    adopt the convention that all properties be prefixed with a namespace
    that identifies the target, e.g. "rel ri:surface = </Shaders/mySurf>".
    
    ## Binding Materials
    
    In the UsdShading model, geometry expresses a binding to a single Material or
    to a set of Materials partitioned by UsdGeomSubsets defined beneath the
    geometry; it is legal to bind a Material at the root (or other sub-prim) of 
    a model, and then bind a different Material to individual gprims, but the
    meaning of inheritance and "ancestral overriding" of Material bindings is 
    left to each render-target to determine.  Since UsdGeom has no concept of 
    shading, we provide the API for binding and unbinding geometry on the API 
    schema UsdShadeMaterialBindingAPI.
    
    ## Material Variation
    
    The entire power of USD VariantSets and all the other composition 
    operators can leveraged when encoding shading variation.  
    UsdShadeMaterial provides facilities for a particular way of building
    "Material variants" in which neither the identity of the Materials themselves
    nor the geometry Material-bindings need to change - instead we vary the
    targeted networks, interface values, and even parameter values within
    a single variantSet.  
    See \\ref UsdShadeMaterial_Variations "Authoring Material Variations" 
    for more details.

    ## Materials Encapsulate their Networks in Namespace
    
    UsdShade requires that all of the shaders that "belong" to the Material 
    live under the Material in namespace. This supports powerful, easy reuse
    of Materials, because it allows us to *reference* a Material from one
    asset (the asset might be a library of Materials) into another asset: USD 
    references compose all descendant prims of the reference target into the 
    referencer's namespace, which means that all of the referenced Material's 
    shader networks will come along with the Material. When referenced in this
    way, Materials can also be [instanced](http://openusd.org/docs/USD-Glossary.html#USDGlossary-Instancing), for ease of deduplication and compactness.
    Finally, Material encapsulation also allows us to 
    \\ref UsdShadeMaterial_BaseMaterial "specialize" child materials from 
    parent materials.
    
    """
    customData = {
        string extraIncludes = '''
#include "pxr/usd/usd/variantSets.h"
#include "pxr/usd/usdGeom/subset.h"
#include "pxr/usd/usdShade/connectableAPI.h"'''
        dictionary schemaTokens = {
            dictionary materialVariant = {
                string doc = """The variant name of material variation
                described on a UsdShadeMaterial.
                """
            }
            dictionary surface = {
                string doc = """Describes the <i>surface</i> output 
                terminal on a UsdShadeMaterial. It is used to define the 
                terminal UsdShadeShader describing the surface of a 
                UsdShadeMaterial.
                """
            }
            dictionary displacement = {
                string doc = """Describes the <i>displacement</i> output 
                terminal on a UsdShadeMaterial. It is used to define the 
                terminal UsdShadeShader describing the displacement of a 
                UsdShadeMaterial.
                """
            }
            dictionary volume = {
                string doc = """Describes the <i>volume</i> output 
                terminal on a UsdShadeMaterial. It is used to define the 
                terminal UsdShadeShader describing the volume of a 
                UsdShadeMaterial.
                """
            }
            dictionary universalRenderContext = {
                string value = ""
                string doc = """Possible value for the "renderContext" parameter
                in \\ref UsdShadeMaterial_Outputs API. Represents the universal
                renderContext. An output with a universal renderContext is 
                applicable to all possible rendering contexts.
                """
            }
        }
    }
) 
{
    token outputs:surface (
        doc = """Represents the universal "surface" output terminal of a
        material."""
        displayGroup = "Outputs"
        customData = {
            string apiName = "surface"
        }
    )
    token outputs:displacement (
        doc = """Represents the universal "displacement" output terminal of a 
        material."""
        displayGroup = "Outputs"
        customData = {
            string apiName = "displacement"
        }
    )
    token outputs:volume (
        doc = """Represents the universal "volume" output terminal of a
        material."""
        displayGroup = "Outputs"
        customData = {
            string apiName = "volume"
        }
    )
}

class Shader "Shader" (
    inherits = </Typed>
    doc = """Base class for all USD shaders. Shaders are the building blocks
    of shading networks. While UsdShadeShader objects are not target specific,
    each renderer or application target may derive its own renderer-specific 
    shader object types from this base, if needed.
    
    Objects of this class generally represent a single shading object, whether
    it exists in the target renderer or not. For example, a texture, a fractal,
    or a mix node.

    The main property of this class is the info:id token, which uniquely 
    identifies the type of this node. The id resolution into a renderable 
    shader target is deferred to the consuming application.

    The purpose of representing them in Usd is two-fold:
    \\li To represent, via "connections" the topology of the shading network
    that must be reconstructed in the renderer. Facilities for authoring and 
    manipulating connections are encapsulated in the Has-A schema 
    UsdShadeConnectableAPI.
    \\li To present a (partial or full) interface of typed input parameters 
    whose values can be set and overridden in Usd, to be provided later at 
    render-time as parameter values to the actual render shader objects. Shader 
    input parameters are encapsulated in the property schema UsdShadeInput.
    """ 
    customData = {
        string extraIncludes = '''
#include "pxr/usd/usdShade/input.h"
#include "pxr/usd/usdShade/output.h"
#include "pxr/usd/ndr/declare.h"
#include "pxr/usd/sdr/shaderNode.h"'''
        dictionary schemaTokens = {
            dictionary universalSourceType = {
                string value = ""
                string doc = """Possible value for the "sourceType" parameter 
                in \\ref UsdShadeShader_ImplementationSource API. Represents 
                the universal or fallback source type.
                """
            }
            dictionary sdrMetadata = {
                string doc = """Dictionary valued metadata key authored on
                Shader prims with implementationSource value of sourceAsset or 
                sourceCode to pass along metadata to the shader parser or 
                compiler. It is also used to author metadata on shader 
                properties in a UsdShade-based shader definition file.
                """
            }
            dictionary subIdentifier = {
                string doc = """This identifier is used in conjunction with a
                specific source asset to indicate a particular definition within
                the source asset, if the source asset specifies more than one
                shader node definition.
                """
            }
        }
    }
) {
    uniform token info:implementationSource = "id" (
        allowedTokens = ["id", "sourceAsset", "sourceCode"]
        doc = """Specifies the attribute that should be consulted to get the 
        shader's implementation or its source code.

        * If set to "id", the "info:id" attribute's value is used to 
        determine the shader source from the shader registry.
        * If set to "sourceAsset", the resolved value of the "info:sourceAsset" 
        attribute corresponding to the desired implementation (or source-type)
        is used to locate the shader source.  A source asset file may also
        specify multiple shader definitions, so there is an optional attribute
        "info:sourceAsset:subIdentifier" whose value should be used to indicate
        a particular shader definition from a source asset file.
        * If set to "sourceCode", the value of "info:sourceCode" attribute 
        corresponding to the desired implementation (or source type) is used as 
        the shader source.
        """
        customData = {
            string apiName = "implementationSource"
        }
    )

    uniform token info:id (
        doc = """The id is an identifier for the type or purpose of the 
        shader. E.g.: Texture or FractalFloat.
        The use of this id will depend on the render target: some will turn it
        into an actual shader path, some will use it to generate shader source 
        code dynamically.
        
        \\sa SetShaderId()
        """
        customData = {
            string apiName = "id"
        }
    )
}

class "ConnectableAPI"
(
    inherits = </APISchemaBase>
    doc = """UsdShadeConnectableAPI is an API schema that provides a common
    interface for creating outputs and making connections between shading 
    parameters and outputs. The interface is common to all UsdShade schemas
    that support Inputs and Outputs, which currently includes UsdShadeShader,
    UsdShadeNodeGraph, and UsdShadeMaterial .

    One can construct a UsdShadeConnectableAPI directly from a UsdPrim, or
    from objects of any of the schema classes listed above.  If it seems
    onerous to need to construct a secondary schema object to interact with
    Inputs and Outputs, keep in mind that any function whose purpose is either
    to walk material/shader networks via their connections, or to create such
    networks, can typically be written entirely in terms of 
    UsdShadeConnectableAPI objects, without needing to care what the underlying
    prim type is.

    Additionally, the most common UsdShadeConnectableAPI behaviors
    (creating Inputs and Outputs, and making connections) are wrapped as
    convenience methods on the prim schema classes (creation) and 
    UsdShadeInput and UsdShadeOutput.
    """ 
    customData = {
        token apiSchemaType = "nonApplied"
        string extraIncludes = """
#include "pxr/usd/usdShade/shader.h"
#include "pxr/usd/usdShade/nodeGraph.h"
    """
    }
)
{
}

class "MaterialBindingAPI"
(
    inherits = </APISchemaBase>
    doc = """UsdShadeMaterialBindingAPI is an API schema that provides an 
    interface for binding materials to prims or collections of prims 
    (represented by UsdCollectionAPI objects). 
    
    In the USD shading model, each renderable gprim computes a single 
    <b>resolved Material</b> that will be used to shade the gprim (exceptions, 
    of course, for gprims that possess UsdGeomSubsets, as each subset can be 
    shaded by a different Material).  A gprim <b>and each of its ancestor 
    prims</b> can possess, through the MaterialBindingAPI, both a 
    <b>direct</b> binding to a Material, and any number of 
    <b>collection-based</b> bindings to Materials; each binding can be generic 
    or declared for a particular <b>purpose</b>, and given a specific <b>binding 
    strength</b>. It is the process of "material resolution" (see 
    \\ref UsdShadeMaterialBindingAPI_MaterialResolution) that examines all of 
    these bindings, and selects the one Material that best matches the 
    client's needs.

    The intent of <b>purpose</b> is that each gprim should be able to resolve a 
    Material for any given purpose, which implies it can have differently bound 
    materials for different purposes. There are two <i>special</i> values of 
    <b>purpose</b> defined in UsdShade, although the API fully supports 
    specifying arbitrary values for it, for the sake of extensibility:
    <ul><li><b>UsdShadeTokens->full</b>: to be used when the purpose of the 
    render is entirely to visualize the truest representation of a scene, 
    considering all lighting and material information, at highest fidelity.</li>  
    <li><b>UsdShadeTokens->preview</b>: to be used when the render is in 
    service of a goal other than a high fidelity "full" render (such as scene
    manipulation, modeling, or realtime playback). Latency and speed are 
    generally of greater concern for preview renders, therefore preview 
    materials are generally designed to be "lighterweight" compared to full
    materials.</li></ul>
    A binding can also have no specific purpose at all, in which 
    case, it is considered to be the fallback or all-purpose binding (denoted 
    by the empty-valued token <b>UsdShadeTokens->allPurpose</b>). 

    The <b>purpose</b> of a material binding is encoded in the name of the 
    binding relationship. 
    <ul><li>
    In the case of a direct binding, the <i>allPurpose</i> binding is 
    represented by the relationship named <b>"material:binding"</b>. 
    Special-purpose direct bindings are represented by relationships named
    <b>"material:binding:<i>purpose</i></b>. A direct binding relationship 
    must have a single target path that points to a <b>UsdShadeMaterial</b>.</li>
    <li>
    In the case of a collection-based binding, the <i>allPurpose</i> binding is 
    represented by a relationship named 
    "material:binding:collection:<i>bindingName</i>", where 
    <b>bindingName</b> establishes an identity for the binding that is unique 
    on the prim. Attempting to establish two collection bindings of the same 
    name on the same prim will result in the first binding simply being 
    overridden. A special-purpose collection-based binding is represented by a 
    relationship named "material:binding:collection:<i>purpose:bindingName</i>".
    A collection-based binding relationship must have exacly two targets, one of 
    which should be a collection-path (see 
    \ref UsdCollectionAPI::GetCollectionPath()) and the other should point to a
    <b>UsdShadeMaterial</b>. In the future, we may allow a single collection 
    binding to target multiple collections, if we can establish a reasonable 
    round-tripping pattern for applications that only allow a single collection 
    to be associated with each Material.
    </li>
    </ul>

    <b>Note:</b> Both <b>bindingName</b> and <b>purpose</b> must be 
    non-namespaced tokens. This allows us to know the role of a binding 
    relationship simply from the number of tokens in it. 
    <ul><li><b>Two tokens</b>: the fallback, "all purpose", direct binding, 
    <i>material:binding</i></li>
    <li><b>Three tokens</b>: a purpose-restricted, direct, fallback binding, 
    e.g. material:binding:preview</li>
    <li><b>Four tokens</b>: an all-purpose, collection-based binding, e.g. 
    material:binding:collection:metalBits</li>
    <li><b>Five tokens</b>: a purpose-restricted, collection-based binding, 
    e.g. material:binding:collection:full:metalBits</li>
    </ul>

    A <b>binding-strength</b> value is used to specify whether a binding 
    authored on a prim should be weaker or stronger than bindings that appear 
    lower in namespace. We encode the binding strength with as token-valued 
    metadata <b>'bindMaterialAs'</b> for future flexibility, even though for 
    now, there are only two possible values:
    <i>UsdShadeTokens->weakerThanDescendants</i> and 
    <i>UsdShadeTokens->strongerThanDescendants</i>. When binding-strength is 
    not authored (i.e. empty) on a binding-relationship, the default behavior 
    matches UsdShadeTokens->weakerThanDescendants.

    \\note If a material binding relationship is a built-in property defined as 
    part of a typed prim's schema, a fallback value should not be provided for 
    it. This is because the "material resolution" algorithm only conisders 
    <i>authored</i> properties.
    """ 
    customData = {
        string extraIncludes = """
#include "pxr/usd/usd/collectionAPI.h"
#include "pxr/usd/usdGeom/subset.h"
#include "pxr/usd/usdShade/material.h"
#include <tbb/concurrent_unordered_map.h>"""
         dictionary schemaTokens = {
            dictionary materialBinding = {
                string value = "material:binding"
                string doc = """
                The relationship name on non-shading prims to
                denote a binding to a UsdShadeMaterial.
                """
            }
            dictionary materialBindingCollection = {
                string value = "material:binding:collection"
                string doc = """ 
                The relationship name on non-shading prims to
                denote a collection-based binding to a UsdShadeMaterial.
                """
            }
            dictionary allPurpose = {
                string value = ""
                string doc = """Possible value for the 'materialPurpose' parameter
                in the various methods available in UsdShadeMaterialBindingAPI.
                Its value is empty and its purpose is to represent a general 
                purpose material-binding that applies in the absence of a 
                specific-purpose binding.
                """
            }
            dictionary preview = {
                string doc = """Possible value for the 'materialPurpose' 
                parameter in UsdShadeMaterialBindingAPI, to be used when the 
                render is in service of a goal other than a high fidelity "full"
                render (such as scene manipulation, modeling, or realtime 
                playback). Latency and speed are generally of greater concern 
                for preview renders, therefore preview materials are generally 
                designed to be "lighterweight" compared to full materials.
                """
            }

            dictionary full = {
                string doc= """Possible value for the 'materialPurpose'
                parameter in UsdShadeMaterialBindingAPI, to be used when the
                purpose of the render is entirely about visualizing the truest
                representation of a scene, considering all lighting and material
                information, at highest fidelity.
                """
            }
            dictionary bindMaterialAs = {
                string doc = """Token valued metadata key authored on a material 
                binding relationship to indicate the strength of the binding 
                relative to bindings authored on descendants.
                """
            }
            dictionary weakerThanDescendants = {
                string doc = """Possible value for 'bindMaterialAs' metadata on the 
                collection-based material binding relationship. Indicates 
                that the binding represented by the relationship is weaker than 
                any bindings authored on the descendants."""
            }
            dictionary strongerThanDescendants = {
                string doc = """Possible value for 'bindMaterialAs' metadata on the 
                collection-based material binding relationship. Indicates 
                that the binding represented by the relationship is stronger than 
                any bindings authored on the descendants."""
            }
            dictionary fallbackStrength = {
                string doc = """Sentinal value to be used for 'bindMaterialAs' 
                metadata's default value. Clients should pass this in for the 
                'bindingStrength' argument to UsdShadeMaterialBindingAPI::Bind(),
                if they want to author the default value (weakerThanDescendants)
                sparsely. The value "fallbackStrength" never gets authored 
                into scene description."""
            }
        }
    }
)
{
    
}

class "CoordSysAPI"
(
    inherits = </APISchemaBase>
    doc = """UsdShadeCoordSysAPI provides a way to designate, name,
    and discover coordinate systems.

    Coordinate systems are implicitly established by UsdGeomXformable
    prims, using their local space.  That coordinate system may be
    bound (i.e., named) from another prim.  The binding is encoded
    as a single-target relationship in the "coordSys:" namespace.
    Coordinate system bindings apply to descendants of the prim
    where the binding is expressed, but names may be re-bound by
    descendant prims.

    Named coordinate systems are useful in shading workflows.
    An example is projection paint, which projects a texture
    from a certain view (the paint coordinate system).  Using
    the paint coordinate frame avoids the need to assign a UV
    set to the object, and can be a concise way to project
    paint across a collection of objects with a single shared
    paint coordinate system.

    This is a non-applied API schema.
    """
    customData = {
        token apiSchemaType = "nonApplied"
        string extraIncludes = '''
#include "pxr/usd/usdGeom/xformable.h"'''
        dictionary schemaTokens = {
            dictionary coordSys = {
                string value = "coordSys:"
                string doc = """Namespace prefix for relationships that
                bind coordinate systems."""
            }
        }
    }
)
{
}
